package cn.xp1997.shiro.x.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * jwt
 * @author xp
 */
public class JwtUtil {



    /**
     * 验证token是否正确
     */
    public static boolean verify(String token) {
        try {
            JWT.decode(token);
            return true;
        } catch (JWTVerificationException exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getKey(String token, String keyName) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(keyName).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }



    /**
     * 根据当前时间生成签名
     * @param key key
     * @param secret   用户的密码
     * @return 加密的token
     */
    public static String sign(String keyName, String key, String secret, Date date) {
        Algorithm algorithm = Algorithm.HMAC256(secret);
        // 附带username信息
        return JWT.create().withClaim(keyName, key).withExpiresAt(date).sign(algorithm);
    }


    /**
     * 根据当前时间生成签名
     * @param keyMap keyName 和 key值
     * @param secret   加密secret
     * @return 加密的token
     */
    public static String sign(Map<String, String> keyMap, String secret, Date date) {
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTCreator.Builder builder = JWT.create();
        //遍历map签名key
        Set<String> keySet = keyMap.keySet();
        for (String key : keySet) {
            builder =  builder.withClaim(key, keyMap.get(key));
        }

        return builder.withExpiresAt(date).sign(algorithm);
    }

    public static Map<String, String> getAll(String token){
        HashMap<String, String> map = new HashMap<>(16);
        DecodedJWT jwt = JWT.decode(token);
        Map<String, Claim> claims = jwt.getClaims();
        claims.forEach((key, value) -> {
            map.put(key, value.asString());
        });
        return map;
    }

}
